package com.duojuhe.coremodule.sms.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.Result;
import com.duojuhe.common.utils.encryption.md5.MD5Util;
import com.duojuhe.common.utils.regexutil.RegexUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import java.util.concurrent.TimeUnit;


/**
 * 短信工具类
 *
 * @date 2018/08/07
 */
@Slf4j
public class SMSUtil {
    /**
     * http请求连接池
     */
    private static OkHttpClient client;

    static {
        //短信通知http连接池配置
        ConnectionPool pool = new ConnectionPool(1, 60 * 3, TimeUnit.SECONDS);
        client = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
                .connectionPool(pool)
                .followRedirects(false)
                .retryOnConnectionFailure(true)
                .build();
    }

    /**
     * 发送短信
     * 模版： https://dx.ipyy.net/smsJson.aspx?action=send&account=4444444&password=898989898989&sendTime=
     *
     * @param mobile   手机号码，以逗号分割
     * @param content  发送内容
     * @param account  华信用户名
     * @param password 华信密码
     */
    public static Result huaXinSendSms(String mobile, String content, String account, String password, String sendIp) {
        try {
            if (StringUtils.isEmpty(sendIp)) {
                log.info("【华信短信】发送IP地址获取失败, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送内容： " + content);
                return Result.fail("发送失败，发送IP地址获取失败!");
            }
            if (StringUtils.isBlank(password) || StringUtils.isBlank(account)) {
                log.info("【华信短信】短信平台账号密码配置错误, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送内容： " + content);
                return Result.fail("发送失败，短信平台账号密码配置错误!");
            }

            if (StringUtils.isBlank(mobile) || StringUtils.isBlank(content)) {
                log.info("【华信短信】手机号码和短信内容不可为空, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送内容： " + content);
                return Result.fail("发送失败，手机号码和短信内容不可为空!");
            }
            if (!RegexUtil.isMobile(mobile.trim())) {
                log.info("【华信短信】手机号码错误，发送失败, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送内容： " + content);
                return Result.fail("发送失败，手机号码错误!");
            }
            String passwordMD5 = MD5Util.getMD532(password);
            RequestBody body = new FormBody.Builder()
                    .add("action", "send")
                    .add("account", account)
                    .add("password", passwordMD5)
                    .add("mobile", mobile)
                    .add("content", content)
                    .build();
            Request request = new Request.Builder()
                    .url("https://dx.ipyy.net/smsJson.aspx")
                    .post(body)
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                ResponseBody responseBody = response.body();
                if (responseBody != null) {
                    String resultStr = responseBody.string();
                    JSONObject jsonObject = JSON.parseObject(resultStr);
                    String successCounts = jsonObject.getString("successCounts");
                    if (StringUtils.equals(String.valueOf(mobile.split(",").length), successCounts)) {
                        log.info("【华信短信】发送成功, 手机号码：" + mobile + ",发送内容： " + content + ",返回值：" + resultStr);
                        return Result.ok("发送成功【华信】");
                    }
                    String message = jsonObject.getString("message");
                    log.info("【华信短信】发送失败, 手机号码：" + mobile + ",发送内容： " + content + ",返回值：" + resultStr);
                    return Result.fail("发送失败，" + message + "【华信】");
                }
            }
            log.info("【华信短信】发送失败, 手机号码：" + mobile + ",发送内容： " + content);
            return Result.fail("发送失败，发送出现异常【华信】");
        } catch (Exception e) {
            log.info("【华信短信】短信发送出现异常, 手机号码：" + mobile + ",发送内容： " + content);
            log.error("【华信短信】发送出现异常, mobile={}, content={}", mobile, content, e);
            return Result.fail(ErrorCodes.SMS_REQUEST_ERROR);
        }
    }

    /**
     * 阿里云 发送短信
     *
     * @param mobile 接收短信的手机号码，多个用英文逗号隔开
     * @param templateCode 短信模板CODE
     * @param templateParam 短信模板变量对应的实际值，eg：{"code":"1234"}
     * @param account 账号
     * @param password 密码
     * @param smsSign 短信签名
     * @param sendIp 短信发送ip
     */
    public static Result aliYunSendSms(String mobile, String templateCode, String templateParam, String account, String password, String smsSign, String sendIp) {
        try {
            if (StringUtils.isEmpty(sendIp)) {
                log.info("【阿里云短信】发送IP地址获取失败, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，发送IP地址获取失败!");
            }
            if (StringUtils.isEmpty(smsSign)) {
                log.info("【阿里云短信】短信签名配置错误, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，短信签名配置错误!");
            }
            if (StringUtils.isBlank(password) || StringUtils.isBlank(account)) {
                log.info("【阿里云短信】短信平台账号密码配置错误, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，短信平台账号密码配置错误!");
            }
            if (StringUtils.isBlank(templateCode)) {
                log.info("【阿里云短信】短信模板CODE不可为空, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，短信模板CODE不可为空!");
            }
            if (StringUtils.isBlank(mobile)) {
                log.info("【阿里云短信】手机号码不可为空, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，手机号码不可为空!");
            }
            if (!RegexUtil.isMobile(mobile.trim())) {
                log.info("【阿里云短信】手机号码错误，发送失败, authority：" + account + ",password： " + password + ",手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.fail("发送失败，手机号码错误!");
            }
            //基础配置
            Config config = new Config();
            config.setEndpoint("dysmsapi.aliyuncs.com");
            config.setAccessKeyId(account);
            config.setAccessKeySecret(password);
            //访问客户端
            Client client = new Client(config);
            //请求参数
            SendSmsRequest sendSmsRequest = new SendSmsRequest();
            sendSmsRequest.setSignName(smsSign);
            sendSmsRequest.setTemplateCode(templateCode);
            sendSmsRequest.setPhoneNumbers(mobile);
            if (StringUtils.isNotBlank(templateParam)){
                sendSmsRequest.setTemplateParam(templateParam);
            }
            RuntimeOptions runtime = new RuntimeOptions();
            //发起请求
            SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime);
            if ("OK".equals(response.body.code)) {
                log.info("【阿里云短信】发送成功, 手机号码：" + mobile + ",发送模板CODE： " + templateCode);
                return Result.ok("发送成功【阿里云】");
            }
            String message = response.body.message;
            log.error("【阿里云短信】发送失败, Message：{},手机号码：{},发送模板CODE：{} ",message,mobile,templateCode);
            return Result.fail("发送失败，" + message);
        } catch (Exception e) {
            log.error("【阿里云短信】发送出现异常, mobile={}, 模板CODE={}", mobile, templateCode, e);
            return Result.fail(ErrorCodes.SMS_REQUEST_ERROR);
        }
    }
}